//按照32字节，即指针为4个字节


/*

什么是多态
	1.概念
		多种形态-》不同对象去完成某个行为会产生不同的状态
	2.分类
	3.实现条件
		a.必须要在继承的环境下
		b.基类的成员函数必须是虚函数，并且子类虚函数必须要对基类中的虚函数进行重写
		c.虚函数调用：虚函数必须要通过基类的指针/引用来调用 

	//体现：根据指针指向或引用的对象不同来调用不同的函数，而具体对象的确定需要在运行时参数传入后 

	4.用伪代码方式举例子
	5.重写
	6.

*/ 

#ifdef a
#include<iostream>
using namespace std;
class Animal {
public:
	Animal(const string& name, const string& gender, size_t age)
		:_name(name)
		,_gender(gender)
		,_age(age)
	{}
	//虚函数
	virtual void Bark() {
		cout << _name << "在叫" << endl;
	}
	virtual void Eat() {
		cout << _name << "在吃" << endl;
	}
public:
	string _name;
	string _gender;
	size_t _age;
};

//必须是继承关系下
class Dog :public Animal {
public:
	Dog(const string& name, const string& gender, size_t age, const string& color)
		:Animal(name, gender, age)
		,_color(color)
	{}
	//被调用函数必须为虚函数，且在派生类中重写
	void Bark() {
		cout << _name << "在汪·汪·汪·！" << endl;
	}
	void Eat() {
		cout << _name << "在啃骨头！" << endl;
	}

public:
	string _color;
};


class Cat :public Animal {
public:
	Cat(const string& name, const string& gender, size_t age, const string& temper)
		:Animal(name, gender, age)
		, _temper(temper)
	{}
	//被调用函数必须为虚函数，且在派生类中重写
	void Bark() {
		cout << _name << "在喵·喵·喵·！" << endl;
	}
	void Eat() {
		cout << _name << "在喝牛奶！" << endl;
	}

public:
	string _temper;
};

void Test(Animal& a) {
	a.Bark();
	a.Eat();
}
void TestPet() {
	Dog d = Dog("花卷", "公", 3, "黑白相间");
	Test(d);

	Cat c("可乐", "女", 2, "黏人");
	Test(c);
}
int main() {
	TestPet();
	return 0;
}
//virtual修饰函数-》虚函数
//编译时不确定，运行时确定具体函数的行为（因为调用前不确定调用的基函数还是某个子类函数，因此为‘虚’函数）

/*
	维基百科对虚函数的定义
	   在面向对象程序设计领域，C++、Object Pascal 等语言中有虚函数（英语：virtual function）或虚方法（英语：virtual method）的概念。
	   这种函数或方法可以被子类继承和覆盖，通常使用动态分派实现。
	   这一概念是面向对象程序设计中（运行时）多态的重要组成部分。
	   简言之，虚函数可以给出目标函数的定义，但该目标的具体指向在编译期可能无法确定。
	
	百度百科
		简单地说，那些被virtual关键字修饰的成员函数，就是虚函数。虚函数的作用，用专业术语来解释就是实现多态性（Polymorphism），
		多态性是将接口与实现进行分离；用形象的语言来解释就是实现以共同的方法，但因个体差异，而采用不同的策略。
	*/

//虚函数：被virtual修饰的类成员函数（全局/友元/...均不可）
#endif

